﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCitySession.h
//    @Author           :    Gao.Yi
//    @Date             :    2025-09-12
//    @Email			:    445267987@qq.com
//    @Module           :    NFCitySession
//    @Desc             :
//
// -------------------------------------------------------------------------

#pragma once

#include "proto_cs_login.nanopb.h"
#include "NFComm/NFObjCommon/NFObject.h"
#include "NFComm/NFShmStl/NFShmString.h"
#include "NFLogicCommon/NFLogicShmTypeDefines.h"
#include "NFLogicCommon/NFPkgMng.h"

class NFCityPlayer;

class NFCitySession : public NF_OBJECT_TEMPLATE_MACRO(NFCitySession, EOT_CITY_SESSION_ID, NFObject)
public:
    NFCitySession();
    ~NFCitySession() override;
    int CreateInit();
    int ResumeInit();
public:
    int OnTimer(int timeId, int callCount) override;
    int Tick();
public:
    // 连接服务器
    int Connect(NFConnectionInfo* pstConnInfo);
    int Connect(const proto_ff::NFConnectionInfo* pstConnInfo);
    // 断开连接
    int DisConnect(int iType, int iReason);
    int CloseConnect();

    // 设置连接信息
    void SetConnInfo(NFConnectionInfo* pstConnInfo)
    {
        m_stConnInfo = *pstConnInfo;
    }

    // 获取连接BUS ID
    int GetConnBusId() const
    {
        return m_stConnInfo.m_iConnBusID;
    }

    // 获取连接索引
    uint64_t GetConnIndex() const
    {
        return m_stConnInfo.m_iConnIdx;
    }

    // 获取OpenID
    std::string GetOpenID() const
    {
        return m_stConnInfo.m_szOpenID.ToString();
    }

    // 获取UIN
    uint64_t GetUIN() const
    {
        return m_stConnInfo.m_ullUin;
    }

    // 设置连接UIN
    void SetConnUin(int64_t uin)
    {
        m_stConnInfo.m_ullUin = uin;
    }

    // 获取登录IP
    std::string GetLoginIP() const
    {
        return m_stConnInfo.m_iLoginIP.ToString();
    }

    // 判断是否为PC端
    bool IsPC() const
    {
        return m_stConnInfo.m_bWorldType == proto_ff::E_PLAT_NONE;
    }

    // 获取平台类型
    char GetPlatformType() const
    {
        return m_stConnInfo.m_chPlatformType;
    }

    // 获取扩展平台类型
    Proto_PlatType GetPlatIDEx()
    {
        return m_stClientInfo.plat_type;
    }

    // 获取平台ID
    int GetPlatID() const
    {
        int platid = 2;

        switch (m_stClientInfo.plat_type)
        {
            case proto_ff::E_PLAT_ANDROID:
                platid = 1;
                break;
            case proto_ff::E_PLAT_IOS:
                platid = 0;
                break;
            default:
                break;
        }

        return platid;
    }

    // 获取世界类型
    int32_t GetWorldType() const
    {
        return m_stConnInfo.m_bWorldType;
    }

    // 获取设备类型
    int32_t GetDeviceType() const;

    // 获取区域ID
    int32_t GetZoneAreaID() const
    {
        return m_iZoneAreaID;
    }

    // 设置区域ID
    void SetZoneAreaID(int iZoneAreaID)
    {
        m_iZoneAreaID = iZoneAreaID;
    }

    // 获取区域ID
    int GetZoneID();

    // 获取连接信息
    const NFConnectionInfo* GetConnInfo()
    {
        return &m_stConnInfo;
    }

    // 获取客户端信息
    const Proto_LoginClientInfo* GetClientInfo()
    {
        return &m_stClientInfo;
    }

    // 获取账号ID
    std::string GetAccountID()
    {
        return m_stConnInfo.m_szOpenID.ToString();
    }

    // 根据登录请求初始化客户端信息
    void InitClientInfoByLoginReq(const proto_ff::Proto_CSLoginReq* pLoginReq);

    // 获取调试信息
    std::string GetDebugInfo() const;

    // 绑定玩家对象
    int BindPlayer(NFCityPlayer* pPlayer);
    // 获取玩家对象
    NFCityPlayer* GetPlayer();
    // 获取活跃玩家对象
    NFCityPlayer* GetActivePlayer();

    // 获取断开连接时间
    uint32_t GetDisConnTime() const
    {
        return m_stConnInfo.m_dwDisConnTime;
    }

    // 设置断开连接时间
    void SetDisconnTime(uint32_t dwDisconnTime)
    {
        m_stConnInfo.m_dwDisConnTime = dwDisconnTime;
    }

    // 获取最后活跃时间
    uint32_t GetLastActiveTime() const
    {
        return m_stConnInfo.m_dwLastActiveTime;
    }

    // 设置最后活跃时间
    void SetLastActiveTime(uint32_t dwTimeStamp)
    {
        m_stConnInfo.m_dwLastActiveTime = dwTimeStamp;
    }

    // 激活并检查
    int ActiveAndCheck(uint16_t wMsgId, uint8_t bSubMsgId, uint32_t activeTime, uint16_t wClientSeq);

    // 登录处理
    int Login(const proto_ff::Proto_CSLoginReq* pLoginReq);
    int Login(const proto_ff::Proto_LoginClientInfo* pClientInfo, int loginPri, int loginZoneId);

    // 获取角色ID
    uint64_t GetRoleId();

    // 获取登录通道
    int GetLoginChannel()
    {
        return m_iLoginChannel;
    }

    // 获取客户端版本标志
    int GetClientVersionFlag()
    {
        return m_bClientVersionFlag;
    }

    // 设置客户端版本标志
    void SetClientVersionFlag(uint8_t bFlag)
    {
        m_bClientVersionFlag = bFlag;
    }

    // 设置延迟停止时间
    void SetDelayStopTime(uint64_t tDelayStopTime)
    {
        m_tDelayStopTime = tDelayStopTime;
    }

    // 获取延迟停止时间
    uint64_t GetDelayStopTime()
    {
        return m_tDelayStopTime;
    }

    // 检查包率
    int CheckPkgRate(int msg_id);

    // 判断是否忙碌
    bool IsBusy() const
    {
        return m_bBusy;
    }

    // 设置忙碌状态
    void SetBusy()
    {
        m_bBusy = true;
    }

    // 清除忙碌状态
    void ClearBusy()
    {
        m_bBusy = false;
    }

    // 增加服务器序列号
    uint16_t IncreaseServerSeq()
    {
        return ++m_wServerSeq;
    }

    // 获取服务器序列号
    uint16_t GetServerSeq() const
    {
        return m_wServerSeq;
    }

    // 存储客户端序列号
    void StoreClientSeq(uint16_t wClientSeq)
    {
        m_wClientSeq = wClientSeq;
    }

    // 获取客户端序列号
    uint16_t GetClientSeq() const
    {
        return m_wClientSeq;
    }

    // 判断是否来自QQ游戏中心
    bool IsFromQQGameCenter();
    // 判断是否来自WX游戏中心
    bool IsFromWXGameCenter();

    // 克隆会话序列号
    int CloneSessionSeq(NFCitySession* pSession);

    // 预注册前处理
    int OnPreRegist(bool bSet);

    // 获取登录优先级
    int GetLoginPri()
    {
        return m_iLoginPri;
    }

    // 设置登录状态
    void SetLogin(bool bSet)
    {
        m_bIsLogin = bSet;
    }

    // 判断是否已登录
    bool IsLogin()
    {
        return m_bIsLogin;
    }

    // 判断是否为招募状态
    bool IsRecruit()
    {
        return m_bIsRecruit;
    }

    // 设置招募状态
    int SetRecruit(bool bRecruit)
    {
        m_bIsRecruit = bRecruit;
        return 0;
    }

    // 获取邀请OpenID
    std::string GetInviteOpenID()
    {
        return m_szInviteOpenID.ToString();
    }

    // 设置邀请OpenID
    int SetInviteOpenID(const std::string& sOpenID)
    {
        m_szInviteOpenID = sOpenID;
        return 0;
    }

    // 获取被邀请者的SOpenID
    std::string GetInvitedSOpenID()
    {
        return m_szInvitedSOpenID.ToString();
    }

    // 设置被邀请者的SOpenID
    int SetInvitedSOpenID(const std::string& sSOpenID)
    {
        m_szInvitedSOpenID = sSOpenID;
        return 0;
    }

    // 设置OpenID
    int SetOpenId(const std::string& szOpenId)
    {
        m_stConnInfo.m_szOpenID = szOpenId;
        return 0;
    }

    // 设置容忍度
    void SetIndulge(bool bindulge) { m_bindulge = bindulge; }

    // 获取容忍度
    bool GetIndulge() { return m_bindulge; }

    // 设置是否为实名认证
    void SetIsRealName(bool real_name) { m_isRealName = real_name; }

    // 获取是否为实名认证
    bool GetIsRealName() { return m_isRealName; }

    bool IsWillDelete() const { return m_isWillDelete; }

    void SetWillDelete();

private:
    // 检查消息ID、时间戳和客户端序列号是否有效
    int Check(uint16_t wMsgId, struct timeval* pstTimeStamp, uint16_t wClientSeq);

public:
    int SendConndStop();

public:
    bool IsLoginQueue() const { return m_bLoginQueue; }
    void SetLoginQueue(bool bLoginQueue) { m_bLoginQueue = bLoginQueue; }

private:
    // 管理包装对象的实例
    NFPkgMng m_stPkgMng;

    // 玩家对象ID
    int m_iPlayerObjID; //bind player id
    // 登录通道ID
    int m_iLoginChannel;
    // 延迟停止时间
    uint64_t m_tDelayStopTime;
    // 是否忙碌
    bool m_bBusy;

    // 玩家指针
    NFCityPlayer* m_pPlayer; //player
    // 连接信息
    NFConnectionInfo m_stConnInfo; //connect info
    // 客户端信息
    Proto_LoginClientInfo m_stClientInfo; //client info
    // 区域ID
    int m_iZoneAreaID;

    // 客户端版本标记
    uint8_t m_bClientVersionFlag; //client version flag

    // 客户端序列号
    uint16_t m_wClientSeq; //current client seq
    // 服务器序列号
    uint16_t m_wServerSeq; //current server seq

    // 是否预注册
    bool m_bPreRegist;
    // 登录优先级
    int m_iLoginPri;

    // 登录区域ID
    int m_iLoginZoneID;
    // 是否已登录
    bool m_bIsLogin;

    // 是否在招人
    bool m_bIsRecruit;
    // 邀请者的OpenID
    NFShmString<128> m_szInviteOpenID;
    // 被邀请者的OpenID
    NFShmString<128> m_szInvitedSOpenID;

    // 是否已计算Android设备数量
    bool m_bAndriodCounted;
    // 是否已计算iOS设备数量
    bool m_bIOSCounted;

    // 是否沉迷
    bool m_bindulge; //该账号是否沉迷 false 表示没有，true 表示有
    // 是否实名认证
    bool m_isRealName; //是否实名
    bool m_isWillDelete; //即将被删除

    bool m_bLoginQueue;
};
